package cn.cjx.org.service.impl;

import cn.cjx.basic.service.impl.BaseServiceImpl;
import cn.cjx.basic.utils.QueryResult;
import cn.cjx.org.domain.Department;
import cn.cjx.org.mapper.DepartmentMapper;
import cn.cjx.org.query.DepartmentQuery;
import cn.cjx.org.service.IDepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 部门的service层实现类
 * @Author: cjx
 * @Version: 1.0
 * @Date: 2022/4/19 18:28
 */
@Service
// 开启只读事务
public class DepartmentServiceImpl extends BaseServiceImpl<Department> implements IDepartmentService {

	@Autowired
	private DepartmentMapper departmentMapper;

	// 基础的CRUD方法从公共接口继承而来

	// 模块自己特有的方法或者CRUD实现不一样时写在这里

	// 根据Id修改
	@Override
	@Transactional
	public void update(Department department) {
		String dirPath = "";
		// 1.判断是哪一级数据，如果是一级，那么dirPath就是我自己的主键Id
		if (department.getParent() == null) {
			// 1.拼接dirPath
			dirPath = "/" + department.getId();
		} else {
			// 1.根据上级部门Id，找到上级部门对象
			Department dept = departmentMapper.loadById(department.getParent().getId());
			// 2.拼接dirPath，因为上级部门的dirPath，已经把整个部门链拼接好了，所以我们作为它的子部门我们的dirPath在
			// 他的基础上拼接自己即可
			if (dept != null) {
				dirPath = dept.getDirPath() + "/" + department.getId();
			}
		}
		// 2.设置dirPath到对象中
		department.setDirPath(dirPath);
		// 3.持久化dirPath到数据库
		departmentMapper.update(department);
	}

	// 新增
	@Override
	@Transactional
	public void save(Department department) {
		departmentMapper.save(department);
		String dirPath = "";
		// 1.判断是哪一级数据，如果是一级，那么dirPath就是我自己的主键Id
		if (department.getParent() == null) {
			// 1.拼接dirPath
			dirPath = "/" + department.getId();
		} else {
			// 1.根据上级部门Id，找到上级部门对象
			Department dept = departmentMapper.loadById(department.getParent().getId());
			// 2.拼接dirPath，因为上级部门的dirPath，已经把整个部门链拼接好了，所以我们作为它的子部门我们的dirPath在
			// 他的基础上拼接自己即可
			if (dept != null) {
				dirPath = dept.getDirPath() + "/" + department.getId();
			}
		}
		// 2.设置dirPath到对象中
		department.setDirPath(dirPath);
		// 3.持久化dirPath到数据库
		departmentMapper.update(department);
	}

	/**
	 * @Title: getTree
	 * @Description: 查询部门树数据
	 * @Author: cjx
	 * @Version: 1.0
	 * @Date: 2022/4/23 15:47
	 * @Parameters: * @param
	 * @Return java.util.List<cn.cjx.org.domain.Department>
	 * 方案四：
	 * - 一次性查询出全部数据
	 * - 从所有数据中找到一级数据
	 * - 只要不是一级数据那就找到自己的上级数据，放入到上级数据的children中
	 */
	@Override
	public List<Department> getTree() {
		// 1.查询出全部数据
		List<Department> depts = departmentMapper.loadAll();


		// 把list集合数据转换为map，stream玩法
		// Map<Long, Department> deptMap = depts.stream().collect(Collectors.toMap(Department::getId, item -> item));
		// 3.把list集合数据转换为map, 普通方式
		Map<Long, Department> deptMap = new HashMap<>();
		for (Department dept : depts) {
			deptMap.put(dept.getId(), dept);
		}
		// 2创建一个空的List，用于装遍历出来的一级对象
		List<Department> trees = new ArrayList<>();
		// 4.从所有数据中找到一级数据 1000条数据
		for (Department dept : depts) { // 循环1000次
			// 3.1.查找到上级Id为空的对象，就是一级对象
			if (dept.getParent_id() == null) {
				// 找到一级，放入到空集合中
				trees.add(dept);
			} else { // 3.2.如果父级Id不为null，那么意味着他是其它级数据
				// 得到父亲
				Department department = deptMap.get(dept.getParent_id());
				if (department != null) {
					// 将儿子放入到父亲中
					department.getChildren().add(dept);
				}
			}
		}

		return trees;
	}


	/**
	 * @Title: getTree
	 * @Description: 查询部门树数据
	 * @Author: cjx
	 * @Version: 1.0
	 * @Date: 2022/4/23 15:47
	 * @Parameters: * @param
	 * @Return java.util.List<cn.cjx.org.domain.Department>
	 *     方案四：
	 *          - 一次性查询出全部数据
	 *          - 从所有数据中找到一级数据
	 *          - 只要不是一级数据那就找到自己的上级数据，放入到上级数据的children中
	 */
    /*@Override
    public List<Department> getTree() {
        // 1.查询出全部数据
        List<Department> depts = departmentMapper.findAll();

        // 创建一个空的List，用于装遍历出来的一级对象
        List<Department> trees = new ArrayList<>();

        // 3.从所有数据中找到一级数据 1000条数据
        for (Department dept : depts) { // 循环1000次
            // 3.1.查找到上级Id为空的对象，就是一级对象
            if (dept.getParent_id() == null){
                // 找到一级，放入到空集合中
                trees.add(dept);
            }else { // 3.2.如果父级Id不为null，那么意味着他是其它级数据
                for (Department departmentParent : depts) { // 循环1000次
                    // 如果当前外层循环对象的父级Id，等于内层循环的id，那么意味着当前外层循环对象是当前内层循环的儿子
                    if(departmentParent.getId() == dept.getParent_id()){
                        // 找到自己父亲之后，放入到父亲的Children字段中
                        departmentParent.getChildren().add(dept);
                        break;
                    }
                }
            }
        }

        return trees;
    }*/
}
